#ifndef JLIB_GRAPHICS_NODES_TEXTNODE_H
#define JLIB_GRAPHICS_NODES_TEXTNODE_H

#include "node.h"
#include "../opengl/shader.h"
#include "../../platform/font.h"

namespace jlib {


struct TextNode : public Node {

  using Node::Node;

  virtual void draw (const mat4 &pv, const mat4 &p, const mat4 &v, const mat4 &m) override;

  bool init (const std::string &path, FileDomain domain = FileDomain::Resource) noexcept;
  void clear () noexcept;

  void setShader (Shader *shader) noexcept;
  void setColor (const rgba &color) noexcept;
  void setBlendFunc (GLenum src, GLenum dst) noexcept;
  void setAnchor (const vec2 &anchor) noexcept;
  void setAnchor (float x, float y) noexcept;
  void setAnchorX (float x) noexcept;
  void setAnchorY (float y) noexcept;

  inline Shader *getShader () noexcept { return this->_shader; }
  inline Texture *getTexture () noexcept { return this->_texture; }
  inline GLenum getSrcBlendFunc () const noexcept { return this->_srcFactor; }
  inline GLenum getDstBlendFunc () const noexcept { return this->_dstFactor; }
  inline vec2 getAnchor () const noexcept { return this->_anchor; }
  inline rgba getColor () const noexcept { return this->_color; }

  void setText (const std::string &text) noexcept;
  void setConfig (const Font::Config &config) noexcept;
  void setAlignment (const size &alignment) noexcept;
  void setSpacing (const size &spacing) noexcept;
  void setTextSize (const size &textSize) noexcept;
  void setAreaSize (const size &areaSize) noexcept;
  void setMinAreaSize (const size &minSize) noexcept;
  void setMaxAreaSize (const size &maxSize) noexcept;

  inline const std::string &getText () const noexcept { return this->_text; }
  inline const Font::Config &getConfig () const noexcept { return this->_config; }
  inline size getAlignment () const noexcept { return this->_config.alignment; }
  inline size getSpacing () const { return this->_config.spacing; }
  inline size getTextSize () const { return this->_config.fontSize; }
  inline size getAreaSize () const { return this->_config.area; }
  inline size getMinAreaSize () const { return this->_config.minArea; }
  inline size getMaxAreaSize () const { return this->_config.maxArea; }

protected:
  void resolveTextTexture () noexcept;
  void resolveVerticesAndTexCoord () noexcept;

  Objptr<Texture> _texture;
  Objptr<Shader> _shader;
  Objptr<Font> _font;
  std::string _text;
  Font::Config _config;

  rgba _color {1.0F, 1.0F, 1.0F, 1.0F};
  rect _txtRect;
  size _boxSize;
  vec2 _vertices[4];
  vec2 _texCoord[4];
  vec2 _anchor {0.5F, 0.5F};

  GLenum _srcFactor {GL_SRC_ALPHA};
  GLenum _dstFactor {GL_ONE_MINUS_SRC_ALPHA};

  flags_type _textNodeFlags {VerticesAndTexCoordDirty};

  constexpr static flags_type VerticesAndTexCoordDirty = 1;
  constexpr static flags_type TextTextureDirty = 2;
  constexpr static flags_type ShaderValid = 4;
  constexpr static flags_type TextureValid = 8;
  constexpr static flags_type Drawable = ShaderValid | TextureValid;

}; // struct TextNode


} // namespace jlib

#endif // JLIB_GRAPHICS_NODES_TEXTNODE_H
